package com.huwei.servie;

import java.util.Date;
import java.util.Objects;
import java.util.UUID;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.huwei.constant.EhcacheConstant;
import com.huwei.constant.JsonResult;
import com.huwei.constant.ResultErrorConstant;
import com.huwei.data.AuthenticationDataSource;
import com.huwei.data.CacheDataSource;
import com.huwei.data.manager.DataSourceManager;
import com.huwei.data.manager.DataSourceManagerFacotry;
import com.huwei.entity.UserAccount;
import com.huwei.util.BeanUtil;
import com.huwei.util.RedisKeyUtil;
import com.huwei.util.cryption.JWT;
import com.huwei.util.cryption.MD5Util;
import com.huwei.util.cryption.Token;
import com.huwei.vo.SmsCodeRequestConstraint;
import com.huwei.vo.TargetCacheInfo;
import com.huwei.vo.UserAccountVo;

@Service
public class AuthenticationService {

	@Autowired
	private DataSourceManagerFacotry dataSourceManagerFacotry;
	@Autowired
	private JWT jwt;
	
	/**
	 * 密码登录
	 * @param userAccount
	 * @return
	 */
	public String loginPassword(UserAccount userAccount) {
		UserAccount oldUser = dataSourceManagerFacotry.getDataManager(AuthenticationDataSource.class).manager().findByUsername(userAccount.getUsername());
		if(Objects.isNull(oldUser) || !MD5Util.valid(userAccount.getPassword(), oldUser.getPassword())) {
			return JsonResult.failed("用户名或密码错误" ,ResultErrorConstant.USER_OR_PASSWORD_ERROR);
		}
		if(oldUser.getStatus() > 1) {
			return JsonResult.failed("账户异常，请联系管理员" ,ResultErrorConstant.USER_OR_PASSWORD_ERROR);
		}
		
		return loginSuccessful(oldUser);
	}

	/**
	 * 	
	 * @param phone
	 * @param smsCode
	 * @return
	 */
	public String loginCode(String phone,String smsCode) {
		String checkInfo = checkSmsCode(phone ,smsCode);
		if(Objects.nonNull(checkInfo)) {
			return checkInfo;
		}
		
		UserAccount oldUser = dataSourceManagerFacotry.getDataManager(AuthenticationDataSource.class).manager().findByPhone(phone);
		if(Objects.isNull(oldUser)) {
			return JsonResult.failed("用户名不存在，请注册",ResultErrorConstant.USER_UNEXISTS);
		}
		if(oldUser.getStatus() > 1) {
			return JsonResult.failed("账户异常，请联系管理员" ,ResultErrorConstant.USER_OR_PASSWORD_ERROR);
		}
		
		return loginSuccessful(oldUser);
	}
	
	public String registerPassword(UserAccount userAccount) {
		UserAccount old = dataSourceManagerFacotry.getDataManager(AuthenticationDataSource.class).manager().findByUsername(userAccount.getUsername());
		if(Objects.nonNull(old)) {
			return JsonResult.failed("您已注册，请勿重复注册", ResultErrorConstant.USER_EXISTS);
		}
		userAccount.setPassword(MD5Util.encypt(userAccount.getPassword()));
		return registerSuccessful(userAccount);
	}

	public String registerCode(UserAccount userAccount, String smsCode) {
		String checkInfo = checkSmsCode(userAccount.getPhone() ,smsCode);
		if(Objects.nonNull(checkInfo)) {
			return checkInfo;
		}
		AuthenticationDataSource ads = dataSourceManagerFacotry.getDataManager(AuthenticationDataSource.class).manager();
		UserAccount old = ads.findByPhone(userAccount.getPhone());
		old = Objects.isNull(old) ? ads.findByUsername(userAccount.getPhone()) : old;
		if(Objects.nonNull(old)) {
			old.setPhone(userAccount.getPhone());
			dataSourceManagerFacotry.getDataManager(AuthenticationDataSource.class).manager().save(old);
			return JsonResult.failed("您已注册，请勿重复注册", ResultErrorConstant.USER_EXISTS);
		}
		userAccount.setUsername(userAccount.getPhone());
		return registerSuccessful(userAccount);
	}
	
	private String loginSuccessful(UserAccount userAccount) {
		userAccount.setLastLoginTime(new Date());
		dataSourceManagerFacotry.getDataManager(AuthenticationDataSource.class).manager().save(userAccount);
		
		return generateToken(userAccount);
	}
	
	private String generateToken(UserAccount userAccount) {
		String userInfoJson = BeanUtil.toJson(new UserAccountVo(userAccount));
		
		Token token = jwt.jwtTokenUtil().createToken(jwt.getSecret(), UUID.randomUUID().toString(), "client", userInfoJson);
		return JsonResult.success(null,BeanUtil.toMap("token", token.getTokenStr()));
	}

	private String registerSuccessful(UserAccount userAccount) {
		initRegisterInfo(userAccount);
		dataSourceManagerFacotry.getDataManager(AuthenticationDataSource.class).manager().save(userAccount);
		return generateToken(userAccount);
	}
	
	private String checkSmsCode(String phone ,String smsCode) {
		String phoneKey = RedisKeyUtil.generateKey(RedisKeyUtil.SMS_KEY_PREFIX, phone);
		DataSourceManager<CacheDataSource> dsm = dataSourceManagerFacotry.getDataManager(CacheDataSource.class);
		SmsCodeRequestConstraint oldSmsCode =  (SmsCodeRequestConstraint) dsm.manager().find(new TargetCacheInfo(EhcacheConstant.CACHE_NAME_SMS_CODE, phoneKey));
		if(oldSmsCode == null) {
			return JsonResult.failed("请先获取验证码", ResultErrorConstant.SMS_CODE_UNEXISTS);
		}
		else if(!smsCode.equals(oldSmsCode.getSmsCode())) {
			return JsonResult.failed("短语验证码错误", ResultErrorConstant.SMS_CODE_ERROR);
		}
		dsm.manager().delete(new TargetCacheInfo(EhcacheConstant.CACHE_NAME_SMS_CODE, phoneKey));
		return null;
	}
	
	private void initRegisterInfo(UserAccount userAccount) {
		Date date = new Date();
		userAccount.setLastLoginIpv4(userAccount.getRegisterIpv4());
		userAccount.setLastLoginIpv6(userAccount.getRegisterIpv6());
		userAccount.setLastLoginTime(date);
		userAccount.setRegisterTime(date);
		userAccount.setUuid(UUID.randomUUID().toString().replace("-", ""));
		userAccount.setStatusModifyTime(date);
		userAccount.setStatus(0);
		userAccount.setStatusModifier("system");
	}
}
